package cn.iocoder.yudao.module.erp.service.gi;

import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.erp.controller.admin.dp.dpdn.vo.DpDnSaveReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.gi.gidn.vo.GiDnPageReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.gi.gidn.vo.GiDnSaveReqVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.dpitem.DpItemDnDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.gi.GiDnDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.giitem.GiItemDnDO;
import cn.iocoder.yudao.module.erp.dal.mysql.gi.GiDnMapper;
import cn.iocoder.yudao.module.erp.dal.mysql.giitem.GiItemDnMapper;
import cn.iocoder.yudao.module.erp.service.dp.DpDnServiceImpl;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.GI_DN_NOT_EXISTS;
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.GI_INCOUNT_NOT_ZERO;


/**
 * ERP物流东宁仓库 Service 实现类
 * @author 天使管理员
 */
@Service
@Validated
public class GiDnServiceImpl implements GiDnService {

    @Resource
    private GiDnMapper giDnMapper;
    @Resource
    private GiItemDnMapper giItemDnMapper;
    @Resource
    private AdminUserService userService;
    @Autowired
    private DpDnServiceImpl dpDnServiceImpl;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String createGiDn(GiDnSaveReqVO createReqVO) {
        Integer inCount = createReqVO.getInCount();
        if (inCount == null || inCount == 0) {
            throw exception(GI_INCOUNT_NOT_ZERO);
        }
        String maxId = generateOrderNumber();
        createReqVO.setId(maxId);
        // 插入
        GiDnDO giDn = BeanUtils.toBean(createReqVO, GiDnDO.class);
        giDnMapper.insert(giDn);
        // 插入子表
        createGiItemDnList(maxId, createReqVO.getGiItemDns());
        // 返回
        return maxId;
    }

    public String generateOrderNumber() {
        // 获取当前日期
        LocalDate currentDate = LocalDate.now();
        // 格式化为 yyyyMMdd
        String dateStr = currentDate.format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        // 获取当前最大单号的前8位和最后四位
        String currentMaxOrderStr = getCurrentMaxOrderNumber();
        if ("0001".equals(currentMaxOrderStr)){
            return "DN" + dateStr + currentMaxOrderStr;
        }
        // 获取当前最大单号的日期部分
        String currentMaxDateStr = currentMaxOrderStr.substring(2, 10);
        // 如果日期不一致，重置序列为0001
        int sequence;
        if (currentMaxDateStr.equals(dateStr)) {
            // 日期一致，则增加序列
            sequence = Integer.parseInt(currentMaxOrderStr.substring(10)) + 1;
        } else {
            // 日期不一致，则重置序列为 0001
            sequence = 1;
        }
        // 生成新的单号
        return "DN" + dateStr + String.format("%04d", sequence);
    }

    // 从数据库中获取当前最大单号
    private String getCurrentMaxOrderNumber() {
        // 此处应从数据库查询获取当前最大单号
        return giDnMapper.getCurrentMaxOrderNumber();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateGiDn(GiDnSaveReqVO updateReqVO) {
        // 更新
        GiDnDO updateObj = BeanUtils.toBean(updateReqVO, GiDnDO.class);
        AdminUserDO user = userService.getUser(getLoginUserId());
        updateObj.setUpdater(user.getUsername());
        giDnMapper.updateById(updateObj);
        // 更新子表
        updateGiItemYwList(updateReqVO.getId(), updateReqVO.getGiItemDns());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteGiDn(String id) {
        // 删除子表
        deleteGiItemDnByNo(id);
        // 删除
        giDnMapper.deleteById(id);
    }

    @Override
    public GiDnDO getGiDn(String id) {
        return giDnMapper.selectById(id);
    }

    @Override
    public PageResult<GiDnDO> getGiDnPage(GiDnPageReqVO pageReqVO) {
        return giDnMapper.selectPage(pageReqVO);
    }

    @Override
    public List<GiItemDnDO> getGiItemDnListByNo(String no) {
        return giItemDnMapper.selectListByNo(no);
    }

    @Override
    public void examineGiDn(GiDnDO giDnDO) {
        // 将 GiDnSaveReqVO 转换为 DpDnSaveReqVO,处理并保存插入到 DpDnSaveReqVO 对应的表
        convertGiDnToDpDn(giDnDO);
        giDnMapper.updateById(giDnDO);
    }

    private void createGiItemDnList(String no, List<GiItemDnDO> list) {
        if (list == null || list.size() == 0){
            return;
        }
        list.forEach(o -> o.setNo(no));
        giItemDnMapper.insertBatch(list);
    }

    private void updateGiItemYwList(String no, List<GiItemDnDO> list) {
        if (list == null || list.size() == 0){
            return;
        }
        deleteGiItemDnByNo(no);
        list.forEach(o -> o.setNo(null)); // 解决更新情况下：1）id 冲突；2）updateTime 不更新
        createGiItemDnList(no, list);
    }

    private void deleteGiItemDnByNo(String no) {
        giItemDnMapper.deleteByNo(no);
    }

    public void convertGiDnToDpDn(GiDnDO giDnDO){
        GiDnDO giDn = giDnMapper.selectById(giDnDO.getId());
        List<GiItemDnDO> giItemDnDOList = giItemDnMapper.selectListByNo(giDn.getId());
        // 复制 GiDnSaveReqVO 中的属性到 DpDnSaveReqVO
        DpDnSaveReqVO createReqVO = BeanUtils.toBean(giDn, DpDnSaveReqVO.class);
        //设置剩余总件数
        createReqVO.setRemCount(giDn.getInCount());
        //设置剩余总体积
        createReqVO.setRemVolume(giDn.getInVolume());
        //设置剩余总重量
        createReqVO.setRemWeight(giDn.getWeight());
        List<DpItemDnDO> dpItemDnS = BeanUtils.toBean(giItemDnDOList, DpItemDnDO.class);
        //设置转换后的列表到 DpDnSaveReqV0
        createReqVO.setDpItemDns(dpItemDnS);
        dpDnServiceImpl.createDpDn(createReqVO);
    }

}